// =======================================================================
// 
//       Filename:  processor.hpp
// 
//    Description:  
// 
//        Version:  1.0
//        Created:  09.04.2010 22:35:13
//       Revision:  none
//       Compiler:  g++
// 
//         Author:  Dominik 'domachine' Burgdörfer (-), dominik.burgdoerfer@googlemail.com
//        Company:  -
// 
// =======================================================================


#ifndef  PROCESSOR_INC
#define  PROCESSOR_INC
#include <boost/shared_ptr.hpp>
#include <boost/any.hpp>
#include <stdexcept>
#include <map>
#include <vector>

namespace webplodder {

    // Forward declarations
    class Plodder;

    namespace page {
        class Page;
    }

    class Plugin;
    class PluginManager;

    namespace templatefile {
        class File;
        class CommandElement;
        class ScriptElement;
        class TextElement;
    }

    namespace navigation {
        class Node;
    }

    namespace utils {
        class CIterator;
    }

    /**
     * @brief This class processes a Page object and
     *        a templatefile::File object and produces
     *        an output file.
     */
    class Processor {
        public:
            /**
             * @brief Constructs a Processor with scriptConfig.
             * @param scriptConfig The script interpreter rules,
             *          used by this instance.
             */
            Processor(std::map<std::string,std::string>&
                    scriptConfig);
            ~Processor();

            /**
             * @brief Process a templatefile::File object and
             *        a Page object to produce an output
             *        file.
             * @param[in] file The templatefile::File object
             *                 produced by the Parser
             * @param[in] page The information to fill
             *                 the templatefile
             */
            void process(page::Page& page);

            /**
             * @brief Installs a PluginManager.
             */
            void installPluginManager(boost::shared_ptr<PluginManager> 
                                                    manager);

            /**
             * @brief Sets the parent Plodder object.
             */
            void setParent(Plodder* parent);

            /**
             * @brief Sets the templatefile::File object.
             */
            void setTemplateFile(templatefile::File& file);

        protected:
            void execSetCmd(const std::vector<boost::any>& args,
                    int line);
            void execNavigationCmd(const std::vector<boost::any>& args,
                    int line,
                    std::ostream& output);
            void execScript(utils::CIterator& input,
                    templatefile::ScriptElement& script,
                    std::ostream& output);
            void processCmd(utils::CIterator& input,
                    templatefile::CommandElement& cmd,
                    std::ostream& output);
            void processText(utils::CIterator& input,
                    templatefile::TextElement& text,
                    std::ostream& output);

        private:
            Plodder* m_parent;
            boost::shared_ptr<PluginManager> m_pluginManager;
            page::Page* m_page;
            bool m_firstRun;
            std::map<std::string,std::string>* m_scriptConfig;
            templatefile::File* m_templateFile;
    };
}
#endif   // ----- #ifndef PROCESSOR_INC  -----
